//=============================================================================
/**
 *
 *	@file		evt_msg.c
 *	@brief		ポケスロン:イベントシーン用メッセージモジュール
 *	@author		hosaka genya
 *	@data		2008.10.03
 *
 */
//=============================================================================
#include "common.h"
#include "gflib/touchpanel.h"
#include "system/fontproc.h"
#include "system/msgdata_util.h"
#include "system/window.h"
#include "system/snd_tool.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_pokethlon.h"
#include "savedata/config.h"

#include "evt_msg.h"

#ifdef PM_DEBUG
	// デバッグ用機能：スタート、セレクトを押しながら起動するとメッセージ速度が変更される
	#define DEBUG_HOOK_MSG_SPEED
#endif // PM_DEBUG

//=============================================================================
/**
 *								定数定義
 */
//=============================================================================
enum
{
	MSG_WAIT		= 20,

	// -- テキストウィンドウの設定値 --
	AGBPOKEMON_FRAMECHR		= 0x3F0,
	AGBPOKEMON_FRAMECOL		= 14,
	AGBPOKEMON_TFRAMECHR	= AGBPOKEMON_FRAMECHR - TALK_WIN_CGX_SIZ,
	AGBPOKEMON_TFRAMECOL	= 13,
};

//=============================================================================
/**
 *								構造体定義
 */
//=============================================================================
typedef struct EVT_MSG_CNT_tag
{
	GF_BGL_INI		*bgl;
	WORDSET			*WordSet;
	MSGDATA_MANAGER	*MsgMng;
	MSGDATA_MANAGER	*MsgMngNpc;
	STRBUF			*MsgBuf;
	HEAPID			HeapID;

	GF_BGL_BMPWIN	MsgWin;
	PKTHLN_GAME_TYPE GameType;
	int				MsgID;

	void*			wkTimeIcon;

	u32				Wait : 16;
	u32				MsgSpeed : 8;
	u32				BgFrm : 3;
	u32				bNextSkipOff : 1;
	u32				bPrinting : 1;
	u32				DummyBit : 3;
}EVT_MSG_CNT;

//=============================================================================
/**
 *							プロトタイプ宣言
 */
//=============================================================================
// -- prototype --
static void MsgWinSet(GF_BGL_INI *bgl, u8 BgFrm, const int inHeapID);
static int CreateMsgWindow(GF_BGL_INI *bgl, GF_BGL_BMPWIN *win, STRBUF **msg, int MsgSpeed,
		WORDSET *word, MSGDATA_MANAGER *msgman, const int inMsgID, const u8 BgFrm, const int inHeapID);

//=============================================================================
/**
 *								外部公開関数
 */
//=============================================================================

//-----------------------------------------------------------------------------
/**
 *	@brief	システム生成
 *
 *	@param	HEAPID HeapID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
MSG_CNT_PTR MSG_CNT_Create( HEAPID HeapID )
{
	MSG_CNT_PTR ptr;

	// メインワーク確保
	ptr = sys_AllocMemory( HeapID, sizeof(EVT_MSG_CNT) );
	//メモリクリア
	MI_CpuClear8( ptr, sizeof(EVT_MSG_CNT) );

	ptr->HeapID = HeapID;

	return ptr;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	初期化
 *
 *	@param	MSG_CNT_PTR ptr
 *	@param	bgl
 *	@param	BgFrm
 *	@param	GameType
 *	@param	p_sv
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MSG_CNT_Init( MSG_CNT_PTR ptr, GF_BGL_INI* bgl, u8 BgFrm, PKTHLN_GAME_TYPE GameType, SAVEDATA* p_sv )
{
	int MsgSpeed = 4; // MSG_SPEED_NORMAL;

	// 一人用ならコンフィグから文字速度を引っ張ってくる
	if( GameType == PKTHLN_GAME_ALONE )
	{
		const CONFIG* cfg = SaveData_GetConfig( p_sv );
		MsgSpeed = CONFIG_GetMsgPrintSpeed( cfg );
	}

#ifdef DEBUG_HOOK_MSG_SPEED
	// デバッグ用機能：スタート、セレクトを押しながら起動するとメッセージ速度が変更される
	{
		static int DebugHookMsgSpeed = 0;

		if( sys.cont & PAD_BUTTON_START )
		{
			DebugHookMsgSpeed = 1;
		}
		else if( sys.cont & PAD_BUTTON_SELECT )
		{
			DebugHookMsgSpeed = 2;
		}

		switch( DebugHookMsgSpeed )
		{
			case 1 : MsgSpeed = 1; break;
			case 2 : MsgSpeed = 8; break;
		}
	}
#endif

	ptr->bgl = bgl;
	ptr->MsgID = MSG_ID_NONE;
	ptr->BgFrm = BgFrm;
	ptr->GameType = GameType;
	ptr->MsgSpeed = MsgSpeed;

	//メッセージマネージャとワードセットの確保
	ptr->MsgMng = MSGMAN_Create(MSGMAN_TYPE_DIRECT, ARC_MSG, NARC_msg_pokethlon_dat, ptr->HeapID);
	ptr->MsgMngNpc = MSGMAN_Create(MSGMAN_TYPE_DIRECT, ARC_MSG, NARC_msg_pokethlon_ctalk_dat, ptr->HeapID);
	ptr->WordSet = WORDSET_Create(ptr->HeapID);

	//プリントタスク初期化
	MSG_PrintInit();
	MsgWinSet(ptr->bgl, ptr->BgFrm, ptr->HeapID);

	/* メッセージのフォントカラーを設定 */
	SystemFontPaletteLoad( PALTYPE_SUB_BG, /*FONT_PALNO_NORMAL*/15 * 32, ptr->HeapID);
	//1キャラ目をＮＵＬＬデータでフィルする
	GF_BGL_CharFill(ptr->bgl, ptr->BgFrm, 0, 1 ,0);
}

//-----------------------------------------------------------------------------
/**
 *	@brief	開放処理
 *
 *	@param	MSG_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MSG_CNT_Delete( MSG_CNT_PTR ptr )
{
	MSGMAN_Delete( ptr->MsgMng );
	MSGMAN_Delete( ptr->MsgMngNpc );
	WORDSET_Delete( ptr->WordSet );

	if ( ptr->MsgBuf!=NULL )
	{
		STRBUF_Delete( ptr->MsgBuf );
	}

	// メインワーク開放
	sys_FreeMemoryEz( ptr );
}


//-----------------------------------------------------------------------------
/**
 *	@brief	メイン処理
 *
 *	@param	MSG_CNT_PTR ptr
 *
 *	@retval	TRUE:メッセージ表示中
 */
//-----------------------------------------------------------------------------
BOOL MSG_CNT_Main( MSG_CNT_PTR ptr )
{
	if ( ptr->MsgID != MSG_ID_NONE )
	{
		// メッセージ終了待ち
		if ( GF_MSG_PrintEndCheck( ptr->MsgID ) == FALSE )
		{
			//表示ウェイトセット
			ptr->Wait = MSG_WAIT;
			//バッファ解放
			STRBUF_Delete( ptr->MsgBuf );
			ptr->MsgBuf = NULL;
			//メッセージＩＤをクリア
			ptr->MsgID = MSG_ID_NONE;
		}
		ptr->bPrinting = TRUE;
	}
	else
	// メッセージ待機
	{
		GF_ASSERT( ptr->MsgID == MSG_ID_NONE );

		if( ptr->Wait > 0 )
		{
			// 一人用
			if( ptr->GameType == PKTHLN_GAME_ALONE )
			{
				ptr->bPrinting = FALSE;
			}
			// 通信用
			else
			{
				//メッセージ表示ウェイト
				ptr->Wait--;
				ptr->bPrinting = ( ptr->Wait > 0 );
			}
		}
		else
		{
			// 通常待機状態
			ptr->bPrinting = FALSE;
		}
	}

	return ptr->bPrinting;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	メッセージプリント
 *
 *	@param	MSG_CNT_PTR ptr
 *	@param	win
 *	@param	inMsgID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MSG_CNT_PrintMessage( MSG_CNT_PTR ptr, int inMsgID )
{
	ptr->MsgID = CreateMsgWindow( ptr->bgl, &ptr->MsgWin, &ptr->MsgBuf, ptr->MsgSpeed,
								  ptr->WordSet, ptr->MsgMng, inMsgID, ptr->BgFrm, ptr->HeapID);
}

//-----------------------------------------------------------------------------
/**
 *	@brief	NPCメッセージプリント
 *
 *	@param	MSG_CNT_PTR ptr
 *	@param	inMsgID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MSG_CNT_PrintNpcMessage( MSG_CNT_PTR ptr, int inMsgID )
{
	ptr->MsgID = CreateMsgWindow( ptr->bgl, &ptr->MsgWin, &ptr->MsgBuf, ptr->MsgSpeed,
								  ptr->WordSet, ptr->MsgMngNpc, inMsgID, ptr->BgFrm, ptr->HeapID);
}

//-----------------------------------------------------------------------------
/**
 *	@brief	次のメッセージウェイトをスキップできなくする
 *
 *	@param	MSG_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MSG_CNT_SetNextMessageSkipOff( MSG_CNT_PTR ptr )
{
	ptr->bNextSkipOff = TRUE;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	プリント強制終了
 *
 *	@param	MSG_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MSG_CNT_PrintEnd( MSG_CNT_PTR ptr )
{
	// 文字表示中ならタスクを終了させる
	if (ptr->MsgID != MSG_ID_NONE)
	{
		HOSAKA_PRINT( "check msg idx : %d \n", ptr->MsgID );
		GF_STR_PrintForceStop( ptr->MsgID );
	}

	if( ptr->MsgWin.ini )
	{
		BmpTalkWinClear( &ptr->MsgWin, WINDOW_TRANS_ON );
		GF_BGL_BmpWinOff( &ptr->MsgWin );
		GF_BGL_BmpWinDel( &ptr->MsgWin );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	ワードセットのポインタを取得
 *
 *	@param	MSG_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
WORDSET* MSG_CNT_GetWordSet( MSG_CNT_PTR ptr )
{
	GF_ASSERT( ptr );
	GF_ASSERT( ptr->WordSet );

	return ptr->WordSet;
}


//-----------------------------------------------------------------------------
/**
 *	@brief	待機アイコンを表示
 *
 *	@param	MSG_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MSG_CNT_TimeWaitIconAdd( MSG_CNT_PTR ptr )
{
	GF_ASSERT( ptr );
	GF_ASSERT( ptr->wkTimeIcon == NULL );

	ptr->wkTimeIcon = TimeWaitIconAdd( &ptr->MsgWin, AGBPOKEMON_TFRAMECHR );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	待機アイコンを消す
 *
 *	@param	MSG_CNT_PTR ptr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MSG_CNT_TimeWaitIconDel( MSG_CNT_PTR ptr )
{
	GF_ASSERT( ptr );
	GF_ASSERT( ptr->wkTimeIcon );

	TimeWaitIconDel( ptr->wkTimeIcon );
}


//=============================================================================
/**
 *								static関数
 */
//=============================================================================

//----------------------------------------------------------------------------
/**
 *	@brief			メッセージウィンドウセット
 *
 *	@param	*bgl		BGL
 *	@param	inHeapID	ヒープID
 *
 *	@return
 */
//-----------------------------------------------------------------------------
static void MsgWinSet(GF_BGL_INI *bgl, u8 BgFrm, const int inHeapID)
{

	// ウィンドウ枠とパレットをＶＲＡＭへロード
	SystemFontPaletteLoad( PALTYPE_SUB_BG, AGBPOKEMON_FRAMECOL * 32, inHeapID);
	TalkWinGraphicSet(bgl, BgFrm, AGBPOKEMON_TFRAMECHR, AGBPOKEMON_TFRAMECOL, /*wk->win_type*/0, inHeapID);
}

//----------------------------------------------------------------------------
/**
 *	@brief	メッセージウィンドウ作成
 *
 *	@param	*bgl		BGL
 *	@param  *win		ビットマップWin
 *	@param  **msg		メッセージバッファポインタ
 *	@param	MsgSpeed	メッセージ速度
 *	@param  *word		ワードセットポインタ
 *	@param  *msgman		メッセージマネージャポインタ
 *	@param  inMsgID		メッセージID
 *	@param	BgFrm		BGのフレーム番号
 *	@param  inHeapID	ヒープID
 *
 *
 *	@return id			生成される文字描画ルーチンのインデックス
 */
//-----------------------------------------------------------------------------
static int CreateMsgWindow(GF_BGL_INI *bgl, GF_BGL_BMPWIN *win, STRBUF **msg, int MsgSpeed,
		WORDSET *word, MSGDATA_MANAGER *msgman,
		const int inMsgID, const u8 BgFrm, const int inHeapID)
{
	int id;

	// ※ 上画面固定
	// ウィンドウが登録されていなければ登録
	if(win->ini == NULL){
		GF_BGL_BmpWinAdd(bgl, win, BgFrm,
			     2, 19, 27, 4,
				 /*FONT_PALNO_NORMAL*/15, 0+1);
	}

	// ウィンドウ内を消去
	GF_BGL_BmpWinDataFill(win, GF_PRINTCOLOR_MAKE(15, 1, 15));

	// アーカイブから展開して表示
	*msg = MSGDAT_UTIL_AllocExpandString(word, msgman, inMsgID, inHeapID);
	id = GF_STR_PrintColor(win, FONT_TALK, *msg, 0, 0, MsgSpeed, GF_PRINTCOLOR_MAKE( 1, 2, 15), NULL);

	BmpTalkWinWrite(win, WINDOW_TRANS_ON, AGBPOKEMON_TFRAMECHR, AGBPOKEMON_TFRAMECOL);

	return id;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	メッセージ表示処理中か否かを返す
 *
 *	@param	MSG_CNT_PTR  ptr
 *
 *	@retval TRUE:表示中
 */
//-----------------------------------------------------------------------------
BOOL MSG_CNT_IsPrinting( MSG_CNT_PTR  ptr )
{
	return ptr->bPrinting;
}
